function [A]=tfile_opt(fullName,screenData)
%TFILE reads the data from an RDI ASCII output file and puts the
% data into Matlab data structures with major groups of:
% Sup - supporing data
% Wat - water data
% Nav - navigation data including GPS.
% Sensor - Sensor data
% Q - discharge related data
%
% The data can be screened (screenData=1) so that invalid data are set to 
% nan or data reflect strictly the ASCII output file (screenData=0). If
% screenData=0 then the data reflect the ASCII file and -32768 and other
% RDI defined values are left in the data structure. If screenData=1 the
% RDI defined values are trapped and set to nan for many variables.
%
% David S. Mueller, USGS, Office of Surface Water
% 7/20/2005
%
% Revision History
%   Fixed HDOP values (PRJ, 3-12-10)
%   Adapted for inADCP classdef (FLE, 8-15-12)
%   Optimized for faster runtime, replaced depreciated strread (FLE, 8-17-12)

fid=fopen(fullName);
clc
disp(sprintf('Scanning Data File: %s',fullName));

% Scan Fixed Leader.
% NOTE: Using fgetl in a while loop is slow. Instead, use fseek to position
% where you want in the file. FLE 8/15/12
fseek(fid, 0, 'eof');
chunksize = ftell(fid);
fseek(fid, 0, 'bof');
ch = fread(fid, chunksize, '*uchar');
fseek(fid, 0, 'bof');
n = sum(ch == sprintf('\n')); % number of lines

% Get the number of bins contained in the file. This is always the
% first fixed value on line 9
bins = cell2mat(textscan(fid,'%f %*[^\n]',1,'headerlines',8));
    
   
% Complete scan of input file.
% Close input file and report that the initial scan is completed.
fclose(fid);
disp('Scan Complete');

% Compute the number of ensembles.
% This is the number of ensembles actually contained in the input file.
noe=round(n/(6+bins));

% Initialize Data Structure.
Sup=struct( 'absorption_dbpm',nan(noe,1),...
            'bins',nan(noe,1),...
            'binSize_cm',nan(1),...
            'nBins',nan(1),...
            'blank_cm',nan(1),...
            'draft_cm',nan(1),...
            'ensNo',nan(noe,1),...
            'nPings',nan(1),...
            'noEnsInSeg',nan(noe,1),...
            'noe',nan(1),...
            'note1',blanks(80),...
            'note2',blanks(80),...
            'intScaleFact_dbpcnt',nan(noe,1),... 
            'intUnits',repmat(blanks(5),noe,1),...
            'vRef',repmat(blanks(4),noe,1),...
            'wm',nan(1),...
            'units',repmat(blanks(2),noe,1),...
            'year',nan(noe,1),...
            'month',nan(noe,1),...
            'day',nan(noe,1),...
            'hour',nan(noe,1),...
            'minute',nan(noe,1),...
            'second',nan(noe,1),...
            'sec100',nan(noe,1),...
            'timeElapsed_sec',nan(noe,1),...
            'timeDelta_sec100',nan(1));

Wat=struct( 'binDepth',nan(bins,noe),...
            'backscatter',nan(bins,noe,4),...
            'vDir',nan(bins,noe),...
            'vMag',nan(bins,noe),...
            'vEast',nan(bins,noe),...
            'vError',nan(bins,noe),...
            'vNorth',nan(bins,noe),...
            'vVert',nan(bins,noe),...
            'percentGood',nan(bins,noe));
            
Nav=struct( 'bvEast',nan(noe,1),...
            'bvError',nan(noe,1),...
            'bvNorth',nan(noe,1),...
            'bvVert',nan(noe,1),...
            'depth',nan(noe,4),...
            'dsDepth',nan(noe,1),...
            'dmg',nan(noe,1),...           
            'length',nan(noe,1),...
            'totDistEast',nan(noe,1),...
            'totDistNorth',nan(noe,1),...
            'altitude',nan(noe,1),...
            'altitudeChng',nan(noe,1),...
            'gpsTotDist',nan(noe,1),...
            'gpsVariable',nan(noe,1),...
            'gpsVeast',nan(noe,1),...
            'gpsVnorth',nan(noe,1),...
            'lat_deg',nan(noe,1),...
            'long_deg',nan(noe,1),...
            'nSats',nan(noe,1),...
            'hdop',nan(noe,1));
        
Sensor=struct(  'pitch_deg',nan(noe,1),... 
                'roll_deg',nan(noe,1),... 
                'heading_deg',nan(noe,1),...
                'temp_degC',nan(noe,1));

Q=struct(   'endDepth',nan(noe,1),...
            'endDist',nan(noe,1),...
            'bot',nan(noe,1),...
            'end',nan(noe,1),...
            'meas',nan(noe,1),...
            'start',nan(noe,1),...
            'top',nan(noe,1),... 
            'unit',nan(bins,noe),...
            'startDepth',nan(noe,1),...
            'startDist',nan(noe,1));

Sup.noe=noe;        

% Reopen File for Reading        
fid=fopen(fullName);
disp(sprintf('Reading Data File'));

% Read Fixed Leader
    Sup.note1=fgetl(fid);
    Sup.note2=fgetl(fid);
    C = textscan(fid,'%u %u %u %u %u %u %u',1);
    [...
        Sup.binSize_cm,...
        Sup.blank_cm,...
        Sup.draft_cm,...
        Sup.nBins,...
        Sup.nPings,...
        Sup.timeDelta_sec100,...
        Sup.wm] = deal(C{:});
   
% Read Variable Leader
for n = 1:noe;
       
        C = textscan(fid,'%u %u %u %u %u %f %f %u %u %f %f %f %f',1);
        [...
            Sup.year(n),...
            Sup.month(n),...
            Sup.day(n),...
            Sup.hour(n),...
            Sup.minute(n),...
            Sup.second(n),...
            Sup.sec100(n),...
            Sup.ensNo(n),...
            Sup.noEnsInSeg(n),...
            Sensor.pitch_deg(n),...
            Sensor.roll_deg(n),...
            Sensor.heading_deg(n),...
            Sensor.temp_degC(n)] = deal(C{:});
        
        C = textscan(fid,'%f %f %f %f %f %f %f %f %f %f %f %f',1);
        [...
            Nav.bvEast(n),...
            Nav.bvNorth(n),...
            Nav.bvVert(n),...
            Nav.bvError(n),...
            Nav.dsDepth(n),...
            Nav.altitude(n),...
            Nav.altitudeChng(n),...
            Nav.gpsVariable(n),...
            Nav.depth(n,1),...
            Nav.depth(n,2),...
            Nav.depth(n,3),...
            Nav.depth(n,4)] = deal(C{:});
    
        if Nav.gpsVariable(n)>0
            Nav.hdop(n)=floor(Nav.gpsVariable(n))/10;  %/10 added 3-12-10 by PRJ (according to TRDI WRII manual)
            Nav.nSats(n)=(Nav.gpsVariable(n)-Nav.hdop(n)*10)*100;
        end;
        
        C = textscan(fid,'%f %f %f %f %f',1);
        [...
            Nav.length(n),...
            Sup.timeElapsed_sec(n),...
            Nav.totDistNorth(n),...
            Nav.totDistEast(n),...
            Nav.dmg(n)] = deal(C{:});
        
        C = textscan(fid,'%f %f %f %f %f',1);
        [...
            Nav.lat_deg(n),...
            Nav.long_deg(n),...
            Nav.gpsVeast(n),...
            Nav.gpsVnorth(n),...
            Nav.gpsTotDist(n)] = deal(C{:});
                
        C = textscan(fid,'%f %f %f %f %f %f %f %f %f',1);
        [...
            Q.meas(n),...
            Q.top(n),...
            Q.bot(n),...
            Q.start(n),...
            Q.startDist(n),...
            Q.end(n),...
            Q.endDist(n),...
            Q.startDepth(n),...
            Q.endDepth(n)] = deal(C{:});
      
        C = textscan(fid,'%f %s %s %s %f %f',1);
        [...
            Sup.bins(n),...
            Sup.units,...
            Sup.vRef,...
            Sup.intUnits,...
            Sup.intScaleFact_dbpcnt(n),...
            Sup.absorption_dbpm(n)]= deal(C{:});
   
% Read Profile Data.   
        C = textscan(fid,'%f %f %f %f %f %f %f %f %f %f %f %f %f',Sup.bins(n));
        [...
            Wat.binDepth(1:Sup.bins(n),n),...
            Wat.vMag(1:Sup.bins(n),n),...
            Wat.vDir(1:Sup.bins(n),n),...
            Wat.vEast(1:Sup.bins(n),n),...
            Wat.vNorth(1:Sup.bins(n),n),...
            Wat.vVert(1:Sup.bins(n),n),...
            Wat.vError(1:Sup.bins(n),n),...
            Wat.backscatter(1:Sup.bins(n),n,1),...
            Wat.backscatter(1:Sup.bins(n),n,2),...
            Wat.backscatter(1:Sup.bins(n),n,3),...
            Wat.backscatter(1:Sup.bins(n),n,4),...
            Wat.percentGood(1:Sup.bins(n),n),...
            Q.unit(1:Sup.bins(n),n)] = deal(C{:});

end % for loop through ensembles

% Close File
fclose(fid);
disp('Data Input Complete');

% Screen Data

if screenData==1
    idx=find(Wat.vNorth==-32768);
    Wat.vNorth(idx)=nan;
    idx=find(Wat.vEast==-32768);
    Wat.vEast(idx)=nan;
    idx=find(Wat.vError==-32768);
    Wat.vError(idx)=nan;
    idx=find(Wat.vVert==-32768);
    Wat.vVert(idx)=nan;
    idx=find(Wat.vMag==-32768);
    Wat.vMag(idx)=nan;
    idx=find(Wat.vDir==-32768);
    Wat.vDir(idx)=nan;
    idx=find(Wat.percentGood==-32768);
    Wat.percentGood(idx)=nan;
    idx=find(Wat.backscatter==-32768);
    Wat.backscatter(idx)=nan;

    idx=find(Nav.bvNorth==-32768);
    Nav.bvNorth(idx)=nan;
    idx=find(Nav.bvEast==-32768);
    Nav.bvEast(idx)=nan;
    idx=find(Wat.vError==-32768);
    Nav.bvError(idx)=nan;
    idx=find(Nav.bvVert==-32768);
    Nav.bvVert(idx)=nan;
    idx=find(Nav.depth==0);
    Nav.depth(idx)=nan;
    idx=find(Nav.lat_deg==30000);
    Nav.lat_deg(idx)=nan;
    idx=find(Nav.long_deg==30000);
    Nav.long_deg(idx)=nan;
    idx=find(Nav.gpsVnorth==-32768);
    Nav.gpsVnorth(idx)=nan;
    idx=find(Nav.gpsVeast==-32768);
    Nav.gpsVeast(idx)=nan;

    idx=find(Q.unit==2147483647);
    Q.unit(idx)=nan;
end;

% Assign Data to One Structure
A.Sup=Sup;
A.Wat=Wat;
A.Nav=Nav;
A.Sensor=Sensor;
A.Q=Q;

end % end function tfile